---------------------------------------
--This module samples value from the ADC and the counter when requested by the MCU.
--It doesn't sample if there is data that is waiting to be transfered to the MCU
--
--Oussama Chammam, IC-control-localization-project team
--KTH, MF2063
--last edit: 2012-11-19
----------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
----------------------------------------

entity sample_data_points is
	port(	
			clk : in std_logic;
			reset : in std_logic;
			
			--control signal from the block "data_deliverer"
			no_more_data_to_transfer : in std_logic;
			
			--control/communicatiopn with the MCU
			start_sampling_ORed : in std_logic;			--tells this module if the MCU requested sampling
			currently_sampling : out std_logic;			--a control bit that tells if there is data ready to be transfered to the MCU; is active low
			
			--the counter value can be read from:
			counter : in std_logic_vector(31 downto 0); 
			
			--external ADC is connected at:
			ADC_ampl: in std_logic_vector(11 downto 0); --measured sample value from external ADC
			ADC_data_ready : in std_logic;				--rising_edge on this signal when a new sample is ready to be read by the FPGA
			
			--control lines for FIFO
			FIFO_W_clk : out std_logic;
			FIFO_full : in std_logic;					--active high
			
			--data bus going to FIFOs
			sample_ADC_to_FIFO: out std_logic_vector(11 downto 0);	  
			sample_counter_to_FIFO: out std_logic_vector(31 downto 0) 
	);
end sample_data_points;  

----------------------------------------


architecture behaviour of sample_data_points is

constant high_level_limit : std_logic_vector(11 downto 0) := x"008";--this constant is tuned so that we have a suitable threshold to detect a logical "high" signal coming from the RF (we run ON-OFF keying)

signal state : std_logic_vector(2 downto 0);						--three states (100, 010, 001)
signal sample_ADC_to_FIFO_buffer : std_logic_vector(11 downto 0);
signal stored_value : std_logic;

begin

	process(clk, reset)
    begin
		if reset = '1' then 									--assynchronous reset
			state <= "100";  
			FIFO_W_clk <= '0';
			sample_ADC_to_FIFO <= b"0000_0000_0000"; 
			sample_counter_to_FIFO <= x"00000000";
			currently_sampling <= '0';			
			stored_value <= '0';
					
		elsif rising_edge(clk) then
			case state is
				when "100" =>									--idle state: waiting for start command from the MCU
					if start_sampling_ORed /= '0' and no_more_data_to_transfer = '1' then --only if nothing is ready to be transfered by the "data_deliverer" block, and the MCU requests sampling, then we can start sampling:
						state <= "010";							--we should then move to next state and wait for the beginning of the RF pulse to start recording it
						currently_sampling <= '1';				--since the MCU requested recording new sample data, we tell it that there is no data ready to be transmitted yet
					end if;
					
				when "010" =>									--waiting for a high value of the signal amplitude to start sampling
					if (ADC_ampl > high_level_limit) then		--if the received signal by the ADC is higher that the threshold, then we assume that it was the pulse that we are were waiting for -> proceed by sampling it.
						-- FUTURE work: check for three consecutive ADC_ampl values that exceeds high_level_limit in order to become sure that what we received is actually a valid pulse and not just a noise
						state <= "001";							--in next state we proceed by sampling the pulse
					end if;

				--OBS! the FIFO_full is delayed by one cycle but that should not effect the procedure below (see buffers in the top_module schematics)
				when "001" =>									--sampling until FIFO is full
					if ADC_data_ready = '1' and stored_value  = '0' and FIFO_full = '0' then --if we have data on the ADC line ready to be stored which we didn't store earlier, and we still have space in the FIFO, then:
						sample_ADC_to_FIFO <= ADC_ampl;			--store the sampeled ADC value into the FIFO
						sample_counter_to_FIFO <= counter;		--store the sampeled counter value into the FIFO
						FIFO_W_clk <= '1';						--create a rising_edge on the write clock line for the FIFO
						stored_value <= '1';					--mark this ADC value as stored in the FIFO
					elsif ADC_data_ready = '0' and stored_value  = '1' and FIFO_full = '0' then --the ADC started to sample next value, then:
						FIFO_W_clk <= '0';						--create a falling_edge on the write clock line for the FIFO
						stored_value <= '0';					--mark the current sampeled value (actually not yet sampeled) as non-stored yet
					elsif FIFO_full = '1' then					--if the FIFO become full, we should stop sampling
						state <= "100";							--return to the idle state
						currently_sampling <= '0';				--tell the MCU that: we are ready with recording all sample data, and the MCU can request readiung the data
					end if;
					
				when others =>
					state <= "100";								--return to idle state
					currently_sampling <= '0';					--tell the MCU that: we are ready and not sampling
			end case;
		end if;
    end process;

end behaviour;
